#pragma once

#include "d3dUtil.h"
#include "LevelElement.h"
#include "float3.h"
class RenderContext;
class InputState;
class ContentManager;
class GraphCamera;

class ParticleSystem :  public LevelElement
{
public:

	enum Type { Fire, Rain, Explosion };

	ParticleSystem(Type type, float3 position, GraphCamera* cam);
	virtual ~ParticleSystem();

	// Time elapsed since the system was reset.
	virtual float GetAge()const;

	virtual void SetEyePos(const D3DXVECTOR3& eyePosW);
	virtual void SetEmitPos(const D3DXVECTOR3& emitPosW);
	virtual void SetEmitDir(const D3DXVECTOR3& emitDirW);

	virtual void Initialize(ContentManager *pContentManager);
	virtual void Tick(const InputState & refInputState);
	virtual void Draw(const RenderContext* pRenderContext, ID3D10ShaderResourceView* shadowdepthmap = 0);
	virtual void Reset();

protected:
 
	Type mType;

	GraphCamera* m_GraphCam;
	UINT mMaxParticles;
	bool mFirstRun;

	float mGameTime;
	float mTimeStep;
	float mAge;

	D3DXVECTOR4 mEyePosW;
	D3DXVECTOR4 mEmitPosW;
	D3DXVECTOR4 mEmitDirW;

	ID3D10InputLayout* m_pVertexLayout;
	ID3D10Buffer* mInitVB;	
	ID3D10Buffer* mDrawVB;
	ID3D10Buffer* mStreamOutVB;
 
	ID3D10ShaderResourceView* mTexArrayRV;
	ID3D10ShaderResourceView* mRandomTexRV;

	ID3D10Effect* mDefaultEffect;
	ID3D10EffectTechnique* mStreamOutTech;
	ID3D10EffectTechnique* mDrawTech;

	ID3D10EffectMatrixVariable* mfxViewProjVar;
	ID3D10EffectScalarVariable* mfxGameTimeVar;
	ID3D10EffectScalarVariable* mfxTimeStepVar;
	ID3D10EffectVectorVariable* mfxEyePosVar;
	ID3D10EffectVectorVariable* mfxEmitPosVar;
	ID3D10EffectVectorVariable* mfxEmitDirVar;
	ID3D10EffectShaderResourceVariable* mfxTexArrayVar;
	ID3D10EffectShaderResourceVariable* mfxRandomTexVar;

	virtual void BuildVertexBuffer();
	virtual void GetEffectVariables(ID3D10Effect* effect);
	virtual void DefineInputlayout();
	virtual void CreateEffect(ContentManager *pContentManager);

private:
	ParticleSystem(const ParticleSystem& t);
	ParticleSystem& operator=(const ParticleSystem& t);
};

class CheckExplosionAge
{
public:
	bool operator()(ParticleSystem* ps)
	{
		if(ps->GetAge() > 1.0f) return true;
		else return false;
	}
};